package Q16_26_Calculator;
import java.util.Stack;
public class QuestionB {
public enum Operator {
ADD, SUBTRACT, MULTIPLY, DIVIDE, BLANK
}
/* Return the operator that occurs as offset. */
public static Operator parseNextOperator(String sequence, int offset) {
if (offset < sequence.length()) {
char op = sequence.charAt(offset);
switch(op) {
case '+': return Operator.ADD;
case '-': return Operator.SUBTRACT;
case '*': return Operator.MULTIPLY;
case '/': return Operator.DIVIDE;
}
}
return Operator.BLANK;
}
/* Return the number that starts at offset. */
public static int parseNextNumber(String seq, int offset) {
StringBuilder sb = new StringBuilder();
while (offset < seq.length() && Character.isDigit(seq.charAt(offset))) {
sb.append(seq.charAt(offset));
offset++;
}
return Integer.parseInt(sb.toString());
}
/* Apply operator: left [op] right. */
public static double applyOp(double left, Operator op, double right) {
if (op == Operator.ADD) {
return left + right;
} else if (op == Operator.SUBTRACT) {
return left - right;
} else if (op == Operator.MULTIPLY) {
return left * right;
} else if (op == Operator.DIVIDE) {
return left / right;
} else {
return right;
}
}
/* Return priority of operator. Mapped so that:
* addition == subtraction < multiplication == division. */
public static int priorityOfOperator(Operator op) {
switch (op) {
case ADD: return 1;
case SUBTRACT: return 1;
case MULTIPLY: return 2;
case DIVIDE: return 2;
case BLANK: return 0;
}
return 0;
}
/* Collapse top until priority(futureTop) > priority(top).
* Collapsing means to pop the top 2 numbers and apply the
* operator popped from the top of the operator stack, and then
* push that onto the numbers stack.*/
public static void collapseTop(Operator futureTop, Stack<Double> numberStack, Stack<Operator> operatorStack) {
while (operatorStack.size() >= 1 && numberStack.size() >= 2) {
if (priorityOfOperator(futureTop) <= priorityOfOperator(operatorStack.peek())) {
double second = numberStack.pop();
double first = numberStack.pop();
Operator op = operatorStack.pop();
double collapsed = applyOp(first, op, second);
numberStack.push(collapsed);
} else {
break;
}
}
}
public static double compute(String sequence) {
Stack<Double> numberStack = new Stack<Double>();
Stack<Operator> operatorStack = new Stack<Operator>();
for (int i = 0; i < sequence.length(); i++) {
try
{
/* Get number and push. */
int value = parseNextNumber(sequence, i);
numberStack.push((double) value);
/* Move to the operator. */
i += Integer.toString(value).length();
if (i >= sequence.length()) {
break;
}
/* Get operator, collapse top as needed, push operator. */
Operator op = parseNextOperator(sequence, i);
collapseTop(op, numberStack, operatorStack);
operatorStack.push(op);
} catch (NumberFormatException ex) {
return Integer.MIN_VALUE;
}
}
/* Do final collapse. */
collapseTop(Operator.BLANK, numberStack, operatorStack);
if (numberStack.size() == 1 && operatorStack.size() == 0) {
return numberStack.pop();
}
return 0;
}
public static void main(String[] args) {
String expression = "6/5*3+4*5/2-12/6*3/3+3+3";
double result = compute(expression);
System.out.println(result);
}
}